package com.example.rlw.mvpplugintest.net;

import android.text.TextUtils;
import android.util.Log;

import com.example.rlw.mvpplugintest.app.MyApp;
import com.example.rlw.mvpplugintest.utils.AtomsUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.orhanobut.logger.Logger;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by rlw on 2018/10/10.
 */

public class NetWorks {
    private static final int DEFAULT_TIMEOUT = 5;
    private static Retrofit mRetrofit;
    private static NetWorks mNetWorks;

    private NetWorks() {
    }

    public static NetWorks getInstance() {
        if (mNetWorks == null) {
            synchronized (NetWorks.class) {
                if (mNetWorks == null) {
                    mNetWorks = new NetWorks();
                }
            }
        }
        return mNetWorks;
    }

    public static Gson gson;

    // 解决 gson 封装的数据类型  当 后台返回数据为空字符串时导致的类型转换异常的问题
    public static Gson buildGson() {
        if (gson == null) {
            gson = new GsonBuilder()
                    .registerTypeAdapter(Integer.class, new GsonNullPase.IntegerDefault0Adapter())
                    .registerTypeAdapter(int.class, new GsonNullPase.IntegerDefault0Adapter())
                    .registerTypeAdapter(Double.class, new GsonNullPase.DoubleDefault0Adapter())
                    .registerTypeAdapter(double.class, new GsonNullPase.DoubleDefault0Adapter())
                    .registerTypeAdapter(Long.class, new GsonNullPase.LongDefault0Adapter())
                    .registerTypeAdapter(long.class, new GsonNullPase.LongDefault0Adapter())
                    .create();

        }
        return gson;
    }

    public static <T> T configRetrofit(Class<T> service) {
        mRetrofit = new Retrofit.Builder()
                .baseUrl("http://192.168.5.38:8080")
                .client(configClient())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(buildGson()))
                .build();
        return mRetrofit.create(service);
    }

    public static <T> T configRetrofit(Class<T> service, Interceptor interceptor) {
        mRetrofit = new Retrofit.Builder()
                .baseUrl("http://192.168.5.38:8080")
                .client(configClient(interceptor))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(buildGson()))
                .build();
        return mRetrofit.create(service);
    }

    // 创建普通的网络客户端
    private static OkHttpClient configClient() {
        return getOkHttpClient().build();
    }

    // 创建下载文件时的网络客户端
    public static OkHttpClient configClient(Interceptor interceptor) {
        return getOkHttpClient().addNetworkInterceptor(interceptor).build();
    }

    public static OkHttpClient.Builder getOkHttpClient() {

        OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder();
        Interceptor headerInterceptor = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request.Builder builder = chain.request().newBuilder();
                builder.header("Content-Type", "application/json; charset=utf-8");
                String token = "";
                if (!TextUtils.isEmpty(token)) {
                    builder.addHeader("token", token);
                }
                return chain.proceed(builder.build());
            }
        };

        Interceptor loggingIntercept = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                //请求体
                Request request = chain.request();
                Logger.e("请求体：" + request.toString());
                RequestBody requestBody = request.body();
                if (requestBody != null) {
                    Buffer buffer1 = new Buffer();
                    requestBody.writeTo(buffer1);
                    Charset charset = Charset.forName("UTF-8");
                    String paramsStr = buffer1.readString(charset);
                    Log.e("请求参数", paramsStr);
                }
                //响应体
                Response response = chain.proceed(request);
                ResponseBody responseBody = response.body();
                BufferedSource source = responseBody.source();
                source.request(Long.MAX_VALUE); // Buffer the entire body.
                Buffer buffer = source.buffer();
                Charset UTF8 = Charset.forName("UTF-8");

                // 从相应头中获取到必要的参数
//                Headers headers = response.headers();
//                String cookie = headers.get("Set-Cookie");

                // todo 打包时注释
                Log.e("响应体：", buffer.clone().readString(UTF8));

                return response;
            }
        };

        okHttpClient.addInterceptor(headerInterceptor);
        okHttpClient.addInterceptor(loggingIntercept);

        // 下边是添加网络缓存
//        File httpCacheDirectory = new File(MyApp.mContext.getExternalCacheDir(), "responses");
//        //设置缓存 10M
//        int cacheSize = 10 * 1024 * 1024;
//        Cache cache = new Cache(httpCacheDirectory, cacheSize);
//        Interceptor writeInterceptor = getWriteInterceptor();
//        Interceptor readInterceptor = getReadInterceptor();
//        okHttpClient.cache(cache);
//        okHttpClient.addInterceptor(readInterceptor);
//        okHttpClient.addNetworkInterceptor(writeInterceptor );

        okHttpClient.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);//5,单位为秒
        return okHttpClient;
    }

    private static Interceptor getReadInterceptor() {
        return chain -> {
            Request request = chain.request();
            if (!AtomsUtils.isNetWorkAvailable(MyApp.mContext)) {
                int maxStale = 60 * 60 * 24 * 28; // 离线时缓存保存4周,单位:秒
                CacheControl tempCacheControl = new CacheControl.Builder()
                        .onlyIfCached()
                        .maxStale(maxStale, TimeUnit.SECONDS)
                        .build();
                request = request.newBuilder()
                        .cacheControl(tempCacheControl)
                        .build();
            }
            return chain.proceed(request);
        };
    }

    private static Interceptor getWriteInterceptor() {
        return chain -> {
            Request request = chain.request();
            Response originalResponse = chain.proceed(request);
            int maxAge = 3 * 10; // 在线缓存在半分钟内可读取 单位:秒
            return originalResponse.newBuilder()
                    .removeHeader("Pragma")// 清除头信息，因为服务器如果不支持，会返回一些干扰信息，不清除下面无法生效
                    .removeHeader("Cache-Control")
                    .header("Cache-Control", "public, max-age=" + maxAge)
                    .build();

        };
    }
}
